from typing import Optional
import httpx

from pddnsc.base import BaseSourceProvider


class GenericHttpSource(BaseSourceProvider):
    """Базовый провайдер получения IP адресов по http/https ссылкам в виде текста.

    Конфигурация:

      - url_v4: *URL* для получения адреса *IPv4*
      - url_v6: *URL* для получения адреса *IPv6*
      - headers (`dict`): словарь дополнительных заголовков (*необязательно*)
    """

    def post_init(self):
        self.url_v4 = self.config.get("url_v4")
        self.url_v6 = self.config.get("url_v6")
        self.headers = self.config.get("headers", {})

    async def fetch_v4_impl(self) -> Optional[str]:
        if not self.url_v4:
            return None

        result = ""
        async with httpx.AsyncClient(
            transport=self.ipv4t, headers=self.headers
        ) as client:
            response = await client.get(self.url_v4)
            if response.is_success:
                result = response.text.strip()
        return result

    async def fetch_v6_impl(self) -> Optional[str]:
        if not self.url_v6:
            return None

        result = ""
        async with httpx.AsyncClient(
            transport=self.ipv6t, headers=self.headers
        ) as client:
            response = await client.get(self.url_v6)
            if response.is_success:
                result = response.text.strip()
        return result


class GenericHttpJsonSource(BaseSourceProvider):
    """Базовый провайдер получения IP адресов по http/https ссылкам в виде json.

    Конфигурация:

      - url_v4: *URL* для получения адреса *IPv4*
      - url_v6: *URL* для получения адреса *IPv6*
      - key_v4: ключ *json* (`int` для списка, `str` для словаря) для *IPv4*
      - key_v6: ключ *json* (`int` для списка, `str` для словаря) для *IPv6*
      - headers (`dict`): словарь дополнительных заголовков (*необязательно*)
    """

    def post_init(self):
        self.url_v4 = self.config.get("url_v4")
        self.url_v6 = self.config.get("url_v6")
        self.key_v4 = self.config.get("key_v4")
        self.key_v6 = self.config.get("key_v6")
        if self.config.get("use_accept", True):
            headers = {"Accept": self.config.get("acept_type", "application/json")}
        else:
            headers = {}
        self.headers = headers.update(self.config.get("headers", {}))

    async def fetch_v4_impl(self) -> Optional[str]:
        if not self.url_v4 or self.key_v4 is None:
            return None

        result = ""
        async with httpx.AsyncClient(
            transport=self.ipv4t, headers=self.headers
        ) as client:
            response = await client.get(self.url_v4)
            if response.is_success:
                result = response.json()[self.key_v4].strip()
        return result

    async def fetch_v6_impl(self) -> Optional[str]:
        if not self.url_v6 or self.key_v6 is None:
            return None

        result = ""
        async with httpx.AsyncClient(
            transport=self.ipv6t, headers=self.headers
        ) as client:
            response = await client.get(self.url_v6)
            if response.is_success:
                result = response.json()[self.key_v6].strip()
        return result
